#include <GameEngine/Graphics/Transformation/gl_transformer3d.h>

#include <GameEngine/Graphics/openGL.h>



#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Default constructor
GLTransformer3d::GLTransformer3d() : Transformer3d<float>() {}

//! Constructor
/*!
 *  Builds a 3D transformer that converts points from1, from2, from3 and from4 into points to1, to2, to3 and to4
 *
 @param from1 The point to transform into to1 in the destination coordinate system
 @param from2 The point to transform into to2 in the destination coordinate system
 @param from3 The point to transform into to3 in the destination coordinate system
 @param from4 The point to transform into to4 in the destination coordinate system
 @param to1 The point in which from1 should be transformed in the destination coordinate system
 @param to2 The point in which from2 should be transformed in the destination coordinate system
 @param to3 The point in which from3 should be transformed in the destination coordinate system
 @param to4 The point in which from4 should be transformed in the destination coordinate system
 @sa Function set_transformation is called by this constructor
 */
GLTransformer3d::GLTransformer3d(const Point3d<float>& from1, const Point3d<float>& from2, const Point3d<float>& from3, const Point3d<float>& from4,
				const Point3d<float>& to1, const Point3d<float>& to2, const Point3d<float>& to3, const Point3d<float>& to4) :
	Transformer3d<float>(from1,from2,from3,from4,to1,to2,to3,to4)
{}

//! Copy constructor
/*!
 @param rhs The transformer to copy
 */
GLTransformer3d::GLTransformer3d(const GLTransformer3d& rhs) : Transformer3d<float>(rhs) {}

//! Destructor
GLTransformer3d::~GLTransformer3d() {}

//! Assignment operator
/*!
 @param rhs The transformer to copy
 */
GLTransformer3d& GLTransformer3d::operator=(const GLTransformer3d& rhs) {
	Transformer3d<float>::operator=(rhs);
	return *this;
}

//! Apply the transformation
void GLTransformer3d::apply_transformation() {
	// Push the modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	// Apply the transformation
	float matrix[16] = {
		matrix_[0][0], matrix_[0][1], matrix_[0][2], 0,
		matrix_[1][0], matrix_[1][1], matrix_[1][2], 0,
		matrix_[2][0], matrix_[2][1], matrix_[2][2], 0,
		matrix_[3][0], matrix_[3][1], matrix_[3][2], 1
	};
	glMultMatrixf(matrix);
}

//! Remove the transformation
void GLTransformer3d::remove_transformation() {
	// Pop the modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif
